package com.insight.entity;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.*;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.Cache;import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.UpdateTimestamp;

import java.time.LocalDateTime;

/**
 * T046: 表元数据实体类
 * 记录数据库表的元数据信息
 *
 * @author Insight Team
 */
@Entity
@Table(name = "metadata_table",
        indexes = {
                @Index(name = "idx_metadata_table_datasource", columnList = "datasource_id"),
                @Index(name = "idx_metadata_table_schema", columnList = "table_schema"),
                @Index(name = "idx_metadata_table_type", columnList = "table_type"),
                @Index(name = "idx_metadata_table_name", columnList = "table_name")
        })
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "metadata")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MetadataTable {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 关联的数据源
     */
    @NotNull(message = "数据源不能为空")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "datasource_id", nullable = false)
    @JsonIgnoreProperties({"tables", "hibernateLazyInitializer", "handler"})
    private DataSource dataSource;

    /**
     * 表名
     */
    @NotNull(message = "表名不能为空")
    @Size(max = 200, message = "表名长度不能超过200")
    @Column(name = "table_name", nullable = false, length = 200)
    private String tableName;

    /**
     * 表注释
     */
    @Column(name = "table_comment", length = 1000)
    private String tableComment;

    /**
     * 表模式/数据库名
     */
    @Column(name = "table_schema", length = 100)
    private String tableSchema;

    /**
     * 表类别
     */
    @Column(name = "table_catalog", length = 100)
    private String tableCatalog;

    /**
     * 表类型 (TABLE, VIEW, SYSTEM TABLE等)
     */
    @Column(name = "table_type", length = 50)
    private String tableType;

    /**
     * 表的行数估算
     */
    @Column(name = "row_count")
    private Long rowCount;
    /**
     * 表的数据大小(字节)
     */
    @Column(name = "data_size_bytes")
    private Long dataSizeBytes;

    /**
     * 表结构哈希值(用于变更检测)
     */
    @Column(name = "structure_hash", length = 64)
    private String structureHash;

    /**
     * 最后一次采集时间
     */
    @Column(name = "last_collected_at")
    private LocalDateTime lastCollectedAt;

    /**
     * 元数据记录创建时间
     */
    @CreationTimestamp
    @Column(name = "created_at", nullable = false, updatable = false)
    private LocalDateTime createdAt;

    /**
     * 元数据记录更新时间
     */
    @UpdateTimestamp
    @Column(name = "updated_at", nullable = false)
    private LocalDateTime updatedAt;

    /**
     * 生命周期回调: 持久化之前
     * 设置默认值,避免null
     */
    @PrePersist
    public void prePersist() {
        if (this.tableType == null) {
            this.tableType = "TABLE";
        }
        if (this.rowCount == null) {
            this.rowCount = 0L;
        }
    }

    /**
     * 业务方法: 获取完整表名 (schema.tableName)
     *
     * @return schema.tableName 或 tableName (如果schema为null)
     */
    public String getFullName() {
        if (tableSchema != null && !tableSchema.isEmpty()) {
            return tableSchema + "." + tableName;
        }
        return tableName;
    }

    /**
     * JSON序列化: 获取数据源名称
     * 用于前端显示数据源信息
     */
    @JsonProperty("datasourceName")
    public String getDatasourceName() {
        return dataSource != null ? dataSource.getName() : null;
    }

    /**
     * JSON序列化: 获取数据源类型
     * 用于前端显示数据源类型(POSTGRESQL, MYSQL等)
     */
    @JsonProperty("datasourceType")
    public String getDatasourceType() {
        return dataSource != null && dataSource.getDbType() != null ? dataSource.getDbType().name() : null;
    }

    /**
     * JSON序列化: 获取数据源状态
     * 用于前端显示数据源是否启用
     */
    @JsonProperty("datasourceStatus")
    public String getDatasourceStatus() {
        return dataSource != null ? (dataSource.getEnabled() ? "启用" : "禁用") : null;
    }

    /**
     * JSON序列化: 获取schema名称(别名)
     * 用于前端显示
     */
    @JsonProperty("schemaName")
    public String getSchemaName() {
        return tableSchema;
    }

    /**
     * JSON序列化: 获取表大小(字节)
     * 用于前端显示
     */
    @JsonProperty("sizeInBytes")
    public Long getSizeInBytes() {
        return dataSizeBytes;
    }
}
